/******
	************************************************************************
	******
	** @project : XDrive_Step
	** @brief   : Stepper motor with multi-function interface and closed loop function. 
	** @brief   : 具有多功能接口和闭环功能的步进电机
	** @author  : unlir (知不知啊)
	** @contacts: QQ.1354077136
	******
	** @address : https://github.com/unlir/XDrive
	******
	************************************************************************
	******
	** {Stepper motor with multi-function interface and closed loop function.}
	** Copyright (c) {2020}  {unlir(知不知啊)}
	** 
	** This program is free software: you can redistribute it and/or modify
	** it under the terms of the GNU General Public License as published by
	** the Free Software Foundation, either version 3 of the License, or
	** (at your option) any later version.
	** 
	** This program is distributed in the hope that it will be useful,
	** but WITHOUT ANY WARRANTY; without even the implied warranty of
	** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	** GNU General Public License for more details.
	** 
	** You should have received a copy of the GNU General Public License
	** along with this program.  If not, see <http://www.gnu.org/licenses/>.
	******
	************************************************************************
******/


//Oneself
#include "gpio.h"

/********** Button **********/
/********** Button **********/
/********** Button **********/
/**
  * @brief  GPIO初始化(Button)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_Button_Init(void)
{
#ifdef BUTTON_OK_GPIO_CLK_ENABLE
    /* 使能GPIO时钟 */
    BUTTON_OK_GPIO_CLK_ENABLE();
    /* 配置OK按钮引脚 */
    gpio_init(BUTTON_OK_GPIO_PORT, 
        GPIO_MODE_IN_FLOATING, 
        GPIO_OSPEED_50MHZ, 
        BUTTON_OK_PIN);

    /* 启用内部上拉（如果硬件没有外部上拉） */
    gpio_pullup_enable(BUTTON_OK_GPIO_PORT, BUTTON_OK_PIN);
#endif

#ifdef BUTTON_UP_GPIO_CLK_ENABLE
    BUTTON_UP_GPIO_CLK_ENABLE();
    gpio_init(BUTTON_UP_GPIO_Port, 
            GPIO_MODE_IN_FLOATING, 
            GPIO_OSPEED_50MHZ, 
            BUTTON_UP_Pin);
#endif

#ifdef BUTTON_DOWN_GPIO_CLK_ENABLE
  /* GPIO Ports Clock Enable*/
  BUTTON_DOWN_GPIO_CLK_ENABLE();		//启用DOWN端口时钟
  /*Configure GPIO pin*/
    gpio_init(BUTTON_DOWN_GPIO_Port, 
        GPIO_MODE_IN_FLOATING, 
        GPIO_OSPEED_50MHZ, 
        BUTTON_DOWN_Pin);
#endif
}

/********** HwElec **********/
/********** HwElec **********/
/********** HwElec **********/
/**
  * @brief  GPIO初始化(HwElec)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_HwElec_Init(void)
{
    /* GPIO Ports Clock Enable*/
    HW_ELEC_AP_GPIO_CLK_ENABLE();		//启用AP端口时钟
    HW_ELEC_AM_GPIO_CLK_ENABLE();		//启用AM端口时钟
    HW_ELEC_BP_GPIO_CLK_ENABLE();		//启用BP端口时钟
    HW_ELEC_BM_GPIO_CLK_ENABLE();		//启用BM端口时钟
    /*Configure GPIO pin Output Level*/
    gpio_bit_reset(HW_ELEC_AP_GPIO_Port, HW_ELEC_AP_Pin);//AP引脚启动输出低电平
    gpio_bit_reset(HW_ELEC_AM_GPIO_Port, HW_ELEC_AM_Pin);//AM引脚启动输出低电平
    gpio_bit_reset(HW_ELEC_BP_GPIO_Port, HW_ELEC_BP_Pin);//BP引脚启动输出低电平
    gpio_bit_reset(HW_ELEC_BM_GPIO_Port, HW_ELEC_BM_Pin);//BM引脚启动输出低电平
	/*Configure GPIO pins*/
    gpio_init(HW_ELEC_AP_GPIO_Port, 
        GPIO_MODE_OUT_PP, 
        GPIO_OSPEED_50MHZ, 
        HW_ELEC_AP_Pin);
	/*Configure GPIO pins*/
    gpio_init(HW_ELEC_AM_GPIO_Port, 
        GPIO_MODE_OUT_PP, 
        GPIO_OSPEED_50MHZ, 
        HW_ELEC_AM_Pin);
	/*Configure GPIO pins*/
    gpio_init(HW_ELEC_BP_GPIO_Port, 
        GPIO_MODE_OUT_PP, 
        GPIO_OSPEED_50MHZ, 
        HW_ELEC_BP_Pin);
	/*Configure GPIO pins*/
    gpio_init(HW_ELEC_BM_GPIO_Port, 
        GPIO_MODE_OUT_PP, 
        GPIO_OSPEED_50MHZ, 
        HW_ELEC_BM_Pin);
}

/********** MT6816 **********/
/********** MT6816 **********/
/********** MT6816 **********/
/**
  * @brief  GPIO初始化(MT6816_ABZ)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_MT6816_ABZ_Init(void)
{
#if (defined SENSOR_HVPP_CLK_ENABLE) || (defined MT6816_ABZ_Z_GPIO_CLK_ENABLE)
  // GPIO_InitTypeDef GPIO_InitStruct = {0};
#endif

#ifdef SENSOR_HVPP_CLK_ENABLE
  /* GPIO Ports Clock Enable */
	SENSOR_HVPP_CLK_ENABLE();						//启用MT6816_HVPP端口时钟
  /*Configure GPIO pin Output Level*/
  gpio_bit_reset(SENSOR_HVPP_GPIO_Port,SENSOR_HVPP_Pin);  //MT6816_HVPP引脚输出低电平,启动PWM+ABZ模式

  /*Configure GPIO pins*/
  gpio_init(SENSOR_HVPP_GPIO_Port, 
    GPIO_MODE_OUT_PP, 
    GPIO_OSPEED_50MHZ, 
    SENSOR_HVPP_Pin);
#endif

#ifdef MT6816_ABZ_Z_GPIO_CLK_ENABLE
  /* GPIO Ports Clock Enable */
  MT6816_ABZ_Z_GPIO_CLK_ENABLE();			//启用MT6816_ABZ_Z端口时钟
  // 配置GPIO模式
  gpio_init(MT6816_ABZ_Z_GPIO_PORT, 
      GPIO_MODE_IN_FLOATING, 
      GPIO_OSPEED_50MHZ, 
      MT6816_ABZ_Z_Pin);
  //启用MT6816_Z中断
  nvic_irq_enable(MT6816_ABZ_Z_EXTI_IRQn, 2U, 0U); 
  // 配置GPIO中断映射（PA10对应EXTI10）
  gpio_exti_source_select(MT6816_ABZ_Z_GPIO_PORT, MT6816_ABZ_Z_Pin);
  // 配置EXTI中断线（需根据引脚号对应EXTI线路）
  exti_init(EXTI_10, EXTI_INTERRUPT, EXTI_TRIG_RISING);
  exti_interrupt_flag_clear(EXTI_10);//清中断标志
#endif
}

/********** Modbus **********/
/********** Modbus **********/
/********** Modbus **********/
/**
  * @brief  GPIO初始化(Modbus)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_Modbus_Init(void)
{
#ifdef Modbus_RS485DIR_GPIO_CLK_ENABLE
	/* GPIO Ports Clock Enable */
	Modbus_RS485DIR_GPIO_CLK_ENABLE();		//启用RS485DIR端口时钟
	/*Configure GPIO pin Output Level*/
	gpio_bit_reset(Modbus_RS485DIR_GPIO_Port,Modbus_RS485DIR_GPIO_Pin);	//DIR引脚启动输出低电平
  /*Configure GPIO pins*/
  gpio_init(Modbus_RS485DIR_GPIO_Port, 
    GPIO_MODE_OUT_PP, 
    GPIO_OSPEED_50MHZ, 
    Modbus_RS485DIR_GPIO_Pin);
#endif
}

/**
  * @brief  GPIO初始化(MT6816_SPI)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_MT6816_SPI_Init(void)
{
#ifdef SENSOR_HVPP_CLK_ENABLE
	/* GPIO Ports Clock Enable */
	SENSOR_HVPP_CLK_ENABLE();						//启用MT6816_HVPP端口时钟
	/*Configure GPIO pin Output Level*/
	gpio_bit_set(SENSOR_HVPP_GPIO_Port, SENSOR_HVPP_Pin);			//MT6816_HVPP引脚输出高电平,启动PWM+SPI模式
  /*Configure GPIO pins*/
  gpio_init(SENSOR_HVPP_GPIO_Port, 
    GPIO_MODE_OUT_PP, 
    GPIO_OSPEED_50MHZ, 
    SENSOR_HVPP_Pin);
#endif
	
	/* GPIO Ports Clock Enable */
	MT6816_SPI_CS_GPIO_CLK_ENABLE();		//启用MT6816_SPI_CS端口时钟
	/*Configure GPIO pin Output Level*/
	gpio_bit_set(MT6816_SPI_CS_GPIO_Port, MT6816_SPI_CS_Pin);	//CS引脚启动输出高电平
  /*Configure GPIO pins*/
  gpio_init(MT6816_SPI_CS_GPIO_Port, 
    GPIO_MODE_OUT_PP, 
    GPIO_OSPEED_50MHZ, 
    MT6816_SPI_CS_Pin);
}

/********** OLED **********/
/********** OLED **********/
/********** OLED **********/
/**
  * @brief  GPIO初始化(OLED)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_OLED_Init(void)
{
#ifdef OLED_SPI_CS_GPIO_CLK_ENABLE
	/********** CS **********/
	/*GPIO Ports Clock Enable*/
	OLED_SPI_CS_GPIO_CLK_ENABLE();		//启用CS端口时钟
	/*Configure GPIO pin Output Level*/
	gpio_bit_reset(OLED_SPI_CS_GPIO_Port, OLED_SPI_CS_Pin);		//CS启动输出低电平
	
  /*Configure GPIO pins*/
  gpio_init(OLED_SPI_CS_GPIO_Port, 
    GPIO_MODE_OUT_PP, 
    GPIO_OSPEED_50MHZ, 
    OLED_SPI_CS_Pin);
#endif
	
	/********** RES **********/
	/*GPIO Ports Clock Enable*/
	OLED_SPI_RES_GPIO_CLK_ENABLE();		//启用RES端口时钟
	/*Configure GPIO pin Output Level*/
	gpio_bit_reset(OLED_SPI_RES_GPIO_Port, OLED_SPI_RES_Pin);		//RES启动输出低电平
	/*Configure GPIO pins*/
  gpio_init(OLED_SPI_RES_GPIO_Port, 
    GPIO_MODE_OUT_PP, 
    GPIO_OSPEED_50MHZ, 
    OLED_SPI_RES_Pin);
	
	/********** DC **********/
	/*GPIO Ports Clock Enable*/
	OLED_SPI_DC_GPIO_CLK_ENABLE();		//启用DC端口时钟
	/*Configure GPIO pin Output Level*/
	gpio_bit_reset(OLED_SPI_DC_GPIO_Port, OLED_SPI_DC_Pin);			//DC启动输出低电平
	/*Configure GPIO pins*/
  gpio_init(OLED_SPI_DC_GPIO_Port, 
    GPIO_MODE_OUT_PP, 
    GPIO_OSPEED_50MHZ, 
    OLED_SPI_DC_Pin);
}

/********** SIGNAL **********/
/********** SIGNAL **********/
/********** SIGNAL **********/
/**
  * @brief  GPIO初始化(SIGNAL_COUNT)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_SIGNAL_COUNT_Init(void)
{
#ifdef SIGNAL_COUNT_ENA_CLK_ENABLE
	/*GPIO Ports Clock Enable*/
	SIGNAL_COUNT_ENA_CLK_ENABLE();		//启用ENA端口时钟
	/*Configure GPIO pins*/
  gpio_init(SIGNAL_COUNT_ENA_GPIO_Port, 
    GPIO_MODE_IN_FLOATING, 
    GPIO_OSPEED_50MHZ, 
    SIGNAL_COUNT_ENA_Pin);
#endif
	
#ifdef SIGNAL_COUNT_DIR_CLK_ENABLE
	/*GPIO Ports Clock Enable*/
	SIGNAL_COUNT_DIR_CLK_ENABLE();		//启用DIR端口时钟
	/*Configure GPIO pins*/
  gpio_init(SIGNAL_COUNT_DIR_GPIO_Port,
    GPIO_MODE_IN_FLOATING,
    GPIO_OSPEED_50MHZ,
    SIGNAL_COUNT_DIR_Pin);
  nvic_irq_enable(SIGNAL_COUNT_DIR_Get_IRQn, 0U, 0U);
  gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_7);
  exti_init(EXTI_7,EXTI_INTERRUPT,EXTI_TRIG_BOTH);
  exti_interrupt_flag_clear(EXTI_7);
#endif
}

/**
  * @brief  GPIO清理(SIGNAL_COUNT)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_SIGNAL_COUNT_DeInit(void)
{
	/*EXTI interrupt deinit*/
  exti_interrupt_disable(EXTI_7);
  // 重置DIR引脚配置
  gpio_init(SIGNAL_COUNT_DIR_GPIO_Port, 
  GPIO_MODE_AIN,         // 模拟输入模式（最低功耗）
  GPIO_OSPEED_2MHZ,      // 低速配置
  SIGNAL_COUNT_DIR_Pin);

  // 重置ENA引脚配置  
  gpio_init(SIGNAL_COUNT_ENA_GPIO_Port,
  GPIO_MODE_AIN,
  GPIO_OSPEED_2MHZ,
  SIGNAL_COUNT_ENA_Pin);
}

/**
  * @brief  GPIO初始化(SIGNAL_PWM)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_SIGNAL_PWM_Init(void)
{
	/*GPIO Ports Clock Enable*/
	SIGNAL_PWM_ENA_CLK_ENABLE();		//启用ENA端口时钟
	SIGNAL_PWM_DIR_CLK_ENABLE();		//启用DIR端口时钟
	/*Configure GPIO pins*/
  gpio_init(SIGNAL_PWM_ENA_GPIO_Port,
    GPIO_MODE_IN_FLOATING,
    GPIO_OSPEED_50MHZ,
    SIGNAL_PWM_ENA_Pin);

	/*Configure GPIO pins*/
  gpio_init(SIGNAL_PWM_DIR_GPIO_Port,
    GPIO_MODE_IN_FLOATING,
    GPIO_OSPEED_50MHZ,
    SIGNAL_PWM_DIR_Pin);
}

/**
  * @brief  GPIO清理(SIGNAL_PWM)
  * @param  NULL
  * @retval NULL
*/
void REIN_GPIO_SIGNAL_PWM_DeInit(void)
{
  // 重置DIR引脚配置
  gpio_init(SIGNAL_PWM_DIR_GPIO_Port, 
    GPIO_MODE_AIN,         // 模拟输入模式（最低功耗）
    GPIO_OSPEED_2MHZ,      // 低速配置
    SIGNAL_PWM_DIR_Pin);
  
    // 重置ENA引脚配置  
    gpio_init(SIGNAL_PWM_ENA_GPIO_Port,
    GPIO_MODE_AIN,
    GPIO_OSPEED_2MHZ,
    SIGNAL_PWM_ENA_Pin);
}

/***
 * @brief  GPIO初始化(HOME)
 * @param  NULL
*/
void REIN_GPIO_HOME_Init(void)
{
#ifdef HOME_GPIO_CLK_ENABLE
    HOME_GPIO_CLK_ENABLE();
    gpio_init(HOME_GPIO_Port,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,HOME_Pin);
    nvic_irq_enable(EXTI10_15_IRQn, 0, 0);
    gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_15);
    exti_init(EXTI_15,EXTI_INTERRUPT,EXTI_TRIG_FALLING);
    exti_interrupt_flag_clear(EXTI_15);//清中断标志
#endif

}

/**
 * @brief 开环模式GPIO初始化
 */
// void OPEN_GPIO_Init(void)
// {
// #ifdef OPEN_ENA_CLK_ENABLE
//     /*GPIO Ports Clock Enable*/
//     OPEN_ENA_CLK_ENABLE();        //启用ENA端口时钟
//     /*Configure GPIO pins*/
//     gpio_init(OPEN_ENA_GPIO_Port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, OPEN_ENA_Pin);
// #endif

// #ifdef OPEN_DIR_CLK_ENABLE
//     /*GPIO Ports Clock Enable*/
//     OPEN_DIR_CLK_ENABLE();        //启用DIR端口时钟
//     /*Configure GPIO pins*/
//     GPIO_InitStruct.Pin = OPEN_DIR_Pin;
//     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;    //输入模式
//     GPIO_InitStruct.Pull = GPIO_NOPULL;                                    //禁用上下拉
//     HAL_GPIO_Init(OPEN_DIR_GPIO_Port, &GPIO_InitStruct);
// #endif

// #ifdef OPEN_PUL_CLK_ENABLE
//     /*GPIO Ports Clock Enable*/
//     OPEN_PUL_CLK_ENABLE();        //启用DIR端口时钟
//     /*Configure GPIO pins*/
//     GPIO_InitStruct.Pin = OPEN_PUL_Pin;
//     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;    //输入模式
//     GPIO_InitStruct.Pull = GPIO_NOPULL;                                    //禁用上下拉
//     HAL_GPIO_Init(OPEN_PUL_GPIO_Port, &GPIO_InitStruct);
//     /*EXTI interrupt init*/
//     HAL_NVIC_EnableIRQ(OPEN_PUL_Get_IRQn);    //使能DIR中断
// #endif
// }

// void OPEN_GPIO_DeInit(void)
// {
//     /*EXTI interrupt deinit*/
//     HAL_NVIC_DisableIRQ(OPEN_PUL_Get_IRQn);    //失能DIR中断
//     /*Configure GPIO pins */
//     HAL_GPIO_DeInit(OPEN_PUL_GPIO_Port, OPEN_PUL_Pin);    //重置PUL
//     HAL_GPIO_DeInit(OPEN_DIR_GPIO_Port, OPEN_DIR_Pin);    //重置DIR
//     HAL_GPIO_DeInit(OPEN_ENA_GPIO_Port, OPEN_ENA_Pin);    //重置ENA
// }
